package com.gadgetscode.mazeboy;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class GameBoard extends JPanel implements Runnable, GameAssets {

	private static final long DELAY = 17;
	private Dimension d;
	private int currentTile;
	private int tileSheetX;
	private int tileSheetY;
	private Stone stone;
	private ArrayList<Stone> stones;
	private Road road;
	private ArrayList<Road> roads;
	private Gold gold;
	private ArrayList<Gold> golds;
	private Wall wall;
	private ArrayList<Wall> walls;
	private Monster monster;
	private ArrayList<Monster> monsters;
	private Boy boy;
	private House house;
	private ImageIcon tiled = new ImageIcon(getClass().getResource("/res/maintiled1.png"));
	private boolean ingame;
	private Thread animator;
	private long beforeTime;
	private long afterTime;
	private long beforeTime1;
	private long afterTime1;
	private double boyColumn;
	private double boyRow;
	private int monsterColumn;
	private int monsterRow;
	private double randomNumber;
	private double seek;
	private double boyRealPositionX;
	private boolean rightleftMove;
	private double boyRealPositionY;
	private boolean updownMove;
	private boolean cangoup;
	private boolean cangoside;
	private Star star;
	private ArrayList<Star> stars;
	private GameTimer gmt;
	private LostLabel ll;
	private WinLabel wl;
	private LoadLabel lb;
	private int nextLevel;
	private int[][] map;
	private int[][] gameobj;
	private int nowLevel;
	private AudioInputStream audioStream;
	private AudioFormat format;
	private DataLine.Info info;
	private Clip audioClip;
	private Clip audioClip1;

	public GameBoard() {
		addKeyListener(new TAdapter());
		setBackground(Color.black);
		setFocusable(true);
		d = new Dimension(BOARD_WIDTH, BOARD_HEIGTH);
		setPreferredSize(d);
		gameInit();
		setDoubleBuffered(true);
	}

	private void gameInit() {
		afterTime = System.currentTimeMillis();
		afterTime1 = System.currentTimeMillis();
		nextLevel();
		if (animator == null || ingame) {
			animator = new Thread(this);
			animator.start();
		}
	}

	private void nextLevel() {
		if(nextLevel <= world.length - 1) {
			stones = new ArrayList<Stone>(0);
			roads = new ArrayList<Road>(0);
			golds = new ArrayList<Gold>(0);
			walls = new ArrayList<Wall>(0);
			monsters = new ArrayList<Monster>(0);
			stars = new ArrayList<Star>(10);
			map = world[nextLevel];
			gameobj = game_world[nextLevel];
			loadSprites(gameobj);
			loadSprites(map);
			loadBanners();
			loadStars();
			//loadSound(); 
			gmt.reset();
			ingame = true;
			nextLevel += 1;
		}
	}

	private void loadBanners() {
		ll = new LostLabel();
		ll.setSourceX(0);
		ll.setSourceY(320);
		ll.setX(30);
		ll.setY(BOARD_HEIGTH/2 - 50);
		ll.setVisible(false);
		lb = new LoadLabel();
		lb.setSourceX(0);
		lb.setSourceY(384);
		lb.setX(30);
		lb.setY(BOARD_HEIGTH/2 - 50);
		lb.setVisible(false);
		wl = new WinLabel();
		wl.setSourceX(0);
		wl.setSourceY(256);
		wl.setX(30);
		wl.setY(BOARD_HEIGTH/2 - 50);
		wl.setVisible(false);
	}

	private void loadStars() {
		for(int i = 0; i < 10; i++) {
			star = new Star();
			star.setSourceX(320);
			star.setSourceY(0);
			star.setX(i * SourceWidth);
			star.setY(0);
			star.setVisible(true);
			stars.add(star);
		}
		gmt = new GameTimer(stars, ll);
	}

	private void loadSprites(int[][] map) {

		for(int row = 0; row < ROWS; row++) {
			for(int column = 0; column < COLS; column++) {
				currentTile = map[row][column];

				if(currentTile != EMPTY) {

					tileSheetX = (int) (Math.floor((currentTile - 1) % tilesheetColumns) * SourceWidth);
					tileSheetY = (int) (Math.floor((currentTile - 1) / tilesheetColumns) * SourceWidth);

					switch (currentTile) {

					case STONE:
						stone = new Stone();
						stone.setSourceX(tileSheetX);
						stone.setSourceY(tileSheetY);
						stone.setX(column * SourceWidth);
						stone.setY(row * SourceWidth);
						stone.setVisible(true);
						stones.add(stone);
						break;

					case ROAD:
						road = new Road();
						road.setSourceX(tileSheetX);
						road.setSourceY(tileSheetY);
						road.setX(column * SourceWidth);
						road.setY(row * SourceWidth);
						road.setVisible(true);
						roads.add(road);
						break;

					case GOLD:
						gold = new Gold();
						gold.setSourceX(tileSheetX);
						gold.setSourceY(tileSheetY);
						gold.setX(column * SourceWidth);
						gold.setY(row * SourceWidth);
						gold.setVisible(true);
						golds.add(gold);
						break;

					case WALL:
						wall = new Wall();
						wall.setSourceX(tileSheetX);
						wall.setSourceY(tileSheetY);
						wall.setX(column * SourceWidth);
						wall.setY(row * SourceHeight);
						wall.setVisible(true);
						walls.add(wall);
						break;

					case MONSTER:
						monster = new Monster();
						monster.setSourceX(tileSheetX);
						monster.setSourceY(tileSheetY);
						monster.setX(column * SourceWidth);
						monster.setY(row * SourceWidth);
						monster.setVisible(true);
						monster.setDirection(RIGHT);
						monster.monsterRightLeft = false;
						monsters.add(monster);
						break;

					case BOY:
						boy = new Boy();
						boy.setSourceX(tileSheetX);
						boy.setSourceY(tileSheetY);
						boy.setX(column * SourceWidth);
						boy.setY(row * SourceWidth);
						boy.setVisible(true);
						boy.setDirection(RIGHT);
						boy.boyRightLeft = false;
						break;

					case HOUSE:
						house = new House();
						house.setSourceX(3 * SourceWidth);
						house.setSourceY(3 * SourceWidth);
						house.setX(column * SourceWidth);
						house.setY(row * SourceWidth);
						house.setImageN(0);
						house.setVisible(true);
						break;

					default:
						break;

					}
				}
			}
		}


	}

	@Override
	public void run() {
		long beforeTime, timeDiff, sleep;

		beforeTime = System.currentTimeMillis();

		while (ingame && gmt.inGame()) {

			repaint();
			checkCollide();
			update();

			timeDiff = System.currentTimeMillis() - beforeTime;
			sleep = DELAY - timeDiff;

			if (sleep < 0) 
				sleep = 5;
			try {
				Thread.sleep(sleep);
			} catch (InterruptedException e) {
				System.out.println("interrupted");
			}
			beforeTime = System.currentTimeMillis();
		}
		gameOver();

	}

	private void checkCollide() {
		for(int i = 0; i < monsters.size(); i++) {
			monster = monsters.get(i);
			if(checkBoyMonsterCollide(boy, monster)) {
				ingame = false;
				ll.setVisible(true);
			}
		}

		for(int i = golds.size()-1; i >= 0; i--) {
			gold = golds.get(i);
			if(checkBoyGoldCollide(boy, gold)) {
				golds.remove(i); 
			}
		}

		if(golds.size() <= 0) {
			ingame = false;
			if(nextLevel > world.length - 1) {
				lb.setVisible(true);
				nextLevel = 0;
			}
			else
				wl.setVisible(true);
		}
	}

	private boolean checkBoyGoldCollide(Boy boy, Gold gold) {
		if( (boy.getX() + (SourceWidth/3) == gold.getX() + (SourceWidth/3)) && boy.getY() + (SourceWidth/3) == gold.getY() + (SourceWidth/3) ) {
			return true;
		} else {
			return false;
		}
	}

	private boolean checkBoyMonsterCollide(Boy boy, Monster monster) {
		if( boy.getX() + 20 + 24 > monster.getX() && boy.getX() + 20 < monster.getX() + SourceWidth && boy.getY() + 14 + 35 > monster.getY() && boy.getY() + 14  < monster.getY() + SourceWidth ) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		drawBackGround(g);
		drawRoad(g);
		drawWall(g);
		drawStone(g); 
		drawGold(g);
		drawMonster(g);
		drawHouse(g);
		drawBoy(g);
		updateCoordinate(g);
		drawStars(g);
		drawBanner(g);
		Toolkit.getDefaultToolkit().sync();
		g.dispose();
	}
	
	private void loadSound() 
	{
	  try
	  {
		  File bear = new File(getClass().getResourceAsStream("/res/bear.mp3").toString());
		  File eat = new File(getClass().getResourceAsStream("/res/eat.mp3").toString());
		  
		  audioStream = AudioSystem.getAudioInputStream(bear);
		  format = audioStream.getFormat();
		  info = new DataLine.Info(Clip.class, format);
		  audioClip = (Clip) AudioSystem.getLine(info);
		  audioClip.open(audioStream);
		  
		  audioStream = AudioSystem.getAudioInputStream(eat);
		  format = audioStream.getFormat();
		  info = new DataLine.Info(Clip.class, format);
		  audioClip1 = (Clip) AudioSystem.getLine(info);
		  audioClip1.loop(Clip.LOOP_CONTINUOUSLY);
		   
		  audioClip1.open(audioStream);
		  
		  audioClip1.start();
		  Thread.sleep(6000);
		  
	  }
	  catch (Exception e)
	  {
	   
	  }
	}

	private void drawBanner(Graphics g) {
		if(ll.isVisible()) {
			g.drawImage(tiled.getImage(), (int)ll.getX(), (int)ll.getY(), (int)(ll.getX() + 580), (int)(ll.getY() + 64), ll.getSourceX(), ll.getSourceY(), (ll.getSourceX()+580), (ll.getSourceY()+64), this);
		} else if(lb.isVisible()) {
			g.drawImage(tiled.getImage(), (int)lb.getX(), (int)lb.getY(), (int)(lb.getX() + 580), (int)(lb.getY() + 64), ll.getSourceX(), lb.getSourceY(), (lb.getSourceX()+580), (lb.getSourceY()+64), this);
		} else if(wl.isVisible()) {
			g.drawImage(tiled.getImage(), (int)wl.getX(), (int)wl.getY(), (int)(wl.getX() + 580), (int)(wl.getY() + 64), wl.getSourceX(), wl.getSourceY(), (wl.getSourceX()+580), (wl.getSourceY()+64), this);
		}
	}

	private void drawStars(Graphics g) {
		for(int i = 0; i < stars.size(); i++) {
			star = stars.get(i);
			g.drawImage(tiled.getImage(), (int)star.getX(), (int)star.getY(), (int)(star.getX() + SourceWidth), (int)(star.getY() + SourceHeight), star.getSourceX(), star.getSourceY(), (star.getSourceX()+SourceWidth), (star.getSourceY()+SourceHeight), this);
		}
	}

	private void drawMonster(Graphics g) {
		for(int i = 0; i < monsters.size(); i++) {
			monster = monsters.get(i);
			g.drawImage(tiled.getImage(), (int)monster.getX(), (int)monster.getY(), (int)(monster.getX() + SourceWidth), (int)(monster.getY() + SourceHeight), monster.getSourceX(), monster.getSourceY(), (monster.getSourceX()+SourceWidth), (monster.getSourceY()+SourceHeight), this);
		}
	}

	private void drawBoy(Graphics g) {
		g.drawImage(tiled.getImage(), (int)boy.getX(), (int)boy.getY(), (int)(boy.getX() + SourceWidth), (int)(boy.getY() + SourceHeight), boy.getSourceX(), boy.getSourceY(), (boy.getSourceX()+SourceWidth), (boy.getSourceY()+SourceHeight), this);
	}

	private void drawHouse(Graphics g) {
		g.drawImage(tiled.getImage(), (int)house.getX(), (int)house.getY(), (int)(house.getX() + SourceWidth), (int)(house.getY() + SourceHeight), house.getSourceX(), house.getSourceY(), (house.getSourceX()+SourceWidth), (house.getSourceY()+SourceHeight), this);
	}

	private void drawBackGround(Graphics g) {
		for(int i = 0; i < ROWS; i++) {
			for(int j = 0; j < COLS; j++) {
				g.drawImage(tiled.getImage(), j * SourceWidth, i * SourceHeight, (j * SourceWidth + SourceWidth), (i * SourceHeight + SourceHeight), 0, 0, (SourceWidth), (SourceHeight), this);

			}
		}
	}

	private void drawGold(Graphics g) {
		for(int i = 0; i < golds.size(); i++) {
			gold = golds.get(i);
			g.drawImage(tiled.getImage(), (int)gold.getX(), (int)gold.getY(), (int)(gold.getX() + SourceWidth), (int)(gold.getY() + SourceHeight), gold.getSourceX(), gold.getSourceY(), (gold.getSourceX()+SourceWidth), (gold.getSourceY()+SourceHeight), this);
		}
	}

	private void drawStone(Graphics g) {
		for(int i = 0; i < stones.size(); i++) {
			stone = stones.get(i);
			g.drawImage(tiled.getImage(), (int)stone.getX(), (int)stone.getY(), (int)(stone.getX() + SourceWidth), (int)(stone.getY() + SourceHeight), stone.getSourceX(), stone.getSourceY(), (stone.getSourceX()+SourceWidth), (stone.getSourceY()+SourceHeight), this);
		}
	}

	private void drawWall(Graphics g) {
		for(int i = 0; i < walls.size(); i++) {
			wall = walls.get(i);
			g.drawImage(tiled.getImage(), (int)wall.getX(), (int)wall.getY(), (int)(wall.getX() + SourceWidth), (int)(wall.getY() + SourceHeight), wall.getSourceX(), wall.getSourceY(), (wall.getSourceX()+SourceWidth), (wall.getSourceY()+SourceHeight), this);
		}

	}

	private void drawRoad(Graphics g) {
		for(int i = 0; i < roads.size(); i++) {
			road = roads.get(i);
			g.drawImage(tiled.getImage(), (int) road.getX(), (int)road.getY(), (int)(road.getX() + SourceWidth), (int)(road.getY() + SourceHeight), road.getSourceX(), road.getSourceY(), (road.getSourceX()+SourceWidth), (road.getSourceY()+SourceHeight), this);
		}

	}

	public void update() {
		beforeTime = System.currentTimeMillis();
		beforeTime1 = System.currentTimeMillis();
		calculateHouseNextPosition();
		calculateBoyNewPosition();
		checkBoyNewPath();
		calculateMonsterNextPosition();
		gmt.tick();
		gmt.removeStar();
		return;
	}

	private void updateCoordinate(Graphics g) {

		g.setColor(Color.WHITE);
		Font small = new Font("Helvetica", Font.BOLD, 14);
		FontMetrics metr = this.getFontMetrics(small);
		String message = "x : " + boy.getX() + "  y : " + boy.getY();
		g.setFont(small);
		g.drawString(message, (BOARD_WIDTH - metr.stringWidth(message))/2, 
				BOARD_WIDTH/2);

	}

	private void checkBoyNewPath() {
		boyColumn = Math.floor(boy.getX() / SourceWidth);
		boyRow = Math.floor(boy.getY() / SourceWidth);
		boyRealPositionX = boy.getX();
		boyRealPositionY = boy.getY();
		rightleftMove = ((boyRealPositionX) % (SourceWidth) !=0);
		cangoup = ((boyRealPositionX) % (SourceWidth) >= 0 || (boyRealPositionX) % (SourceWidth) < 9);
		cangoside = ((boyRealPositionY) % (SourceWidth) >= 0 || (boyRealPositionY) % (SourceWidth) < 9);
		updownMove = ((boyRealPositionY) % (SourceWidth) != 0);
		if(boy.getDirection() == RIGHT) {
			if(boyColumn <= COLS-1) {
				int thingToTheRight = map[(int) boyRow][(int) (boyColumn + 1)];
				if((thingToTheRight != WALL && thingToTheRight != STONE) && cangoside) {			
					boy.setX(boy.getX()+boy.dx);
					boy.setY(boyRow * SourceWidth);
				} else if(rightleftMove) {
					boy.setX(boy.getX()+boy.dx);
				}
			} 
		} else if(boy.getDirection() == LEFT) {
			if(boyColumn > 0 ) {
				int thingToTheLeft = map[(int) boyRow][(int) (boyColumn-1)];
				if((thingToTheLeft != WALL && thingToTheLeft != STONE) && cangoside) {
					boy.setX(boy.getX()+boy.dx);
					boy.setY(boyRow * SourceWidth);
				} else if(rightleftMove) {
					boy.setX(boy.getX()+boy.dx);
				}

			} 
		} else if(boy.getDirection() == UP) {
			if(boyRow > 0) {
				int thingAbove = map[(int) (boyRow-1)][(int) boyColumn];					
				if(thingAbove != WALL && thingAbove != STONE && cangoup) {
					boy.setY(boy.getY()+boy.dy);
					boy.setX(boyColumn * SourceWidth);
				} else if(updownMove) {
					boy.setY(boy.getY()+boy.dy);
				}
			} 
		} else {
			if(boyRow <= ROWS-1) {
				int thingBelow = map[(int) (boyRow + 1)][(int) boyColumn];	
				if(thingBelow != WALL && thingBelow != STONE && cangoup) {
					boy.setY(boy.getY()+boy.dy);
					boy.setX(boyColumn * SourceWidth);
				}  else if(updownMove) {
					boy.setY(boy.getY()+boy.dy);
				}
			} 
		}

	}

	private void gameOver() {
		while(animator != null) {
			try {
				animator.join();
				animator = null;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void calculateMonsterNextPosition() {
		for(int i = 0; i < monsters.size(); i++) {
			monster = monsters.get(i);
			normalDirection(monster);
			calculateMonsterNewPosition(monster);
		}
	}

	private void calculateMonsterNewPosition(Monster monster) {

		if(monster.getDirection() == RIGHT) {
			monster.setSourceX(192);
			monster.setSourceY(0);
		} else if(monster.getDirection() == LEFT) {
			monster.setSourceX(0);
			monster.setSourceY(64);
		} else if(monster.getDirection() == UP) {
			monster.setSourceX(64);
			monster.setSourceY(64);
		}  else {
			monster.setSourceX(128);
			monster.setSourceY(64);
		}
	}

	private void normalDirection(Monster monster) {
		monsterColumn = (int) Math.floor(monster.getX() / SourceWidth);
		monsterRow = (int) Math.floor(monster.getY() / SourceWidth);
		if(monster.getDirection() == RIGHT) {
			if(monsterColumn <= COLS-1) {
				int thingToTheRight = map[monsterRow][(monsterColumn + 1)];
				if(thingToTheRight != WALL && thingToTheRight != HOUSE && thingToTheRight != STONE){	
					if((monster.getY()% SourceWidth) == 0)
						monster.setX(monster.getX() + 2);		
				} else {
					if((monster.getX() % SourceWidth) == 0)
						changeDirection(monster);
					else
						if((monster.getY()% SourceWidth) == 0)
							monster.setX(monster.getX() + 2);	
				}
			} 
		} else if(monster.getDirection() == LEFT) {
			if(monsterColumn > 0 ) {
				int thingToTheLeft = map[monsterRow][(monsterColumn-1)];
				if(thingToTheLeft != WALL && thingToTheLeft != HOUSE && thingToTheLeft != STONE) {
					if((monster.getY()% SourceWidth) == 0)
						monster.setX(monster.getX() - 2);
				} else {
					if((monster.getX() % SourceWidth) == 0)
						changeDirection(monster);
					else
						if((monster.getY()% SourceWidth) == 0)
							monster.setX(monster.getX() - 2);
				}
			} 
		} else if(monster.getDirection() == UP) {
			if(monsterRow > 0) {
				int thingAbove = map[(monsterRow-1)][monsterColumn];					
				if(thingAbove != WALL && thingAbove != HOUSE && thingAbove != STONE) {
					monster.setY(monster.getY() - 2);

				} else {
					if((monster.getY() % SourceWidth) == 0)
						changeDirection(monster);
					else
						monster.setY(monster.getY() - 2);
				}
			} 
		} else if(monster.getDirection() == DOWN) {
			if(monsterRow <= ROWS-1) {
				int thingBelow = map[(monsterRow + 1)][monsterColumn];	
				if(thingBelow != WALL && thingBelow != HOUSE && thingBelow != STONE) {
					monster.setY(monster.getY() + 2);
				} else {
					if((monster.getY() % SourceWidth) == 0)
						changeDirection(monster);
					else
						monster.setY(monster.getY() + 2);
				}
			} 
		}


	}

	private void changeDirection(Monster monster) {
		monsterColumn = (int) Math.floor(monster.getX() / SourceWidth);
		monsterRow = (int) Math.floor(monster.getY() / SourceWidth);
		monster.validDirections = new ArrayList<Integer>(0);

		if(monsterRow > 0) {
			int thingAbove = map[(monsterRow-1)][monsterColumn];				
			if(thingAbove != WALL && thingAbove != HOUSE && thingAbove != STONE) {	
				monster.validDirections.add(UP);
			} 
		} 

		if(monsterRow <= ROWS-1) {
			int thingBelow = map[(monsterRow + 1)][monsterColumn];	
			if(thingBelow != WALL && thingBelow != HOUSE && thingBelow != STONE) {
				monster.validDirections.add(DOWN);
			} 
		} 


		if(monsterColumn > 0 ) {
			int thingToTheLeft = map[monsterRow][(monsterColumn-1)];
			if(thingToTheLeft != WALL && thingToTheLeft != HOUSE && thingToTheLeft != STONE) {
				monster.validDirections.add(LEFT);
			} 
		} 

		if(monsterColumn <= COLS-1  ) {
			int thingToTheRight = map[monsterRow][(monsterColumn + 1)];
			if(thingToTheRight != WALL && thingToTheRight != HOUSE && thingToTheRight != STONE) {			
				monster.validDirections.add(RIGHT);			
			} 
		} 

		if(monster.validDirections.size() != 0) {

			boolean upOrDownPassage = (monster.validDirections.contains(UP)  || monster.validDirections.contains(DOWN));
			boolean leftOrRightPassage = (monster.validDirections.contains(LEFT) || monster.validDirections.contains(RIGHT));

			if((upOrDownPassage && leftOrRightPassage) || monster.validDirections.size() >= 1) {
				randomNumber = Math.floor(Math.random() * monster.validDirections.size());
				seek = Math.floor(Math.random() * 2);
				if(seek > 0) {
					findClosestDirection(monster);
				} else {
					monster.setDirection(monster.validDirections.get((int) randomNumber));
				}
				if(monster.getDirection() == RIGHT) {
					if((monster.getY()% SourceWidth) == 0)
						monster.setX(monster.getX()+2);
				} else if(monster.getDirection() == LEFT) {	 
					if((monster.getY()% SourceWidth) == 0)
						monster.setX(monster.getX()-2);
				} else if(monster.getDirection() == UP) {
					monster.setY(monster.getY()-2);
				} else if(monster.getDirection() == DOWN) {	
					monster.setY(monster.getY()+2);
				}
			}	
		} 	
	}

	private void findClosestDirection(Monster monster) {
		int closestDirection;
		double dx = boy.getX()-monster.getX();
		double dy = boy.getY()-monster.getY();
		boolean found = false;
		if(Math.abs(dx) <= Math.abs(dy)) {
			if(dx <= 0) {
				closestDirection = LEFT;
			} else {
				closestDirection = RIGHT;
			}
		} else {
			if(dy <= 0) {
				closestDirection = UP;
			} else {
				closestDirection = DOWN;
			}
		}

		for(int i = 0; i < monster.validDirections.size(); i++) {
			if(closestDirection == monster.validDirections.get(i)) {
				monster.setDirection(closestDirection);
				found = true;
				break;
			}
		}

		if(!found) {
			monster.setDirection(monster.validDirections.get((int) randomNumber));	
		}

	}

	private void calculateBoyNewPosition() {
		if(beforeTime1 - afterTime1 > 130) {
			if(boy.getDirection() == RIGHT) {
				if(boy.boyRightLeft == true) {
					boy.setSourceX(256);
					boy.setSourceY(0);
					boy.boyRightLeft = false;
				} else {
					boy.setSourceX(256);
					boy.setSourceY(64);
					boy.boyRightLeft = true;
				}
			} else if(boy.getDirection() == LEFT) {
				if(boy.boyLeftRight == true) {
					boy.setSourceX(64);
					boy.setSourceY(192);
					boy.boyLeftRight = false;
				} else {
					boy.setSourceX(128);
					boy.setSourceY(192);
					boy.boyLeftRight = true;
				}
			} else if(boy.getDirection() == UP) {
				if(boy.boyUpLeft == true) {
					boy.setSourceX(320);
					boy.setSourceY(128);
					boy.boyUpLeft = false;
				} else {
					boy.setSourceX(0);
					boy.setSourceY(192);
					boy.boyUpLeft = true;
				}
			}  else {

				if(boy.boyDownRight == true) {
					boy.setSourceX(320);
					boy.setSourceY(64);
					boy.boyDownRight = false;
				} else {
					boy.setSourceX(0);
					boy.setSourceY(128);
					boy.boyDownRight = true;
				}
			}
			afterTime1 = beforeTime1;
		}
	}

	private void calculateHouseNextPosition() {

		if(beforeTime - afterTime > 500) {

			if(house.getImageN() == 0) {
				house.setSourceX(192);
				house.setSourceY(192);
				house.setImageN(1);
			} else if(house.getImageN() == 1) {
				house.setSourceX(256);
				house.setSourceY(192);
				house.setImageN(2);
			} else if(house.getImageN() == 2) {
				house.setSourceX(320);
				house.setSourceY(192);
				house.setImageN(0);
			}
			afterTime = beforeTime;
		}
	}

	private class TAdapter extends KeyAdapter {

		public void keyReleased(KeyEvent e) {
			boy.keyReleased(e);
		}

		public void keyPressed(KeyEvent e) {
			nextLevelBegin(e);
			restartGame(e);
			boy.keyPressed(e);
		}
	}

	public void restartGame(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_ENTER && (ll.isVisible())) {
			nextLevel -= 1;
			gameInit();
		}
		
	}

	public void nextLevelBegin(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_ENTER && (wl.isVisible() || lb.isVisible())) {
			gameInit();
		}
	}

}
